import React, { useState, useEffect, useImperativeHandle } from 'react';
import { Menu, Dropdown, message, Row, Col } from 'antd';
import PopValue from 'src/components/PopTab/PopValue';
import ConditionsIndex from 'src/components/Conditions/ConditionsIndex';
import { validateConditions } from 'src/components/Conditions/validate';
import { validateActions } from 'src/components/Actions/validate';
import Actions from 'src/components/Actions';
import { randomKey } from 'src/utils/utils';
import { cloneDeep, flattenDepth } from 'lodash';
import { compareClass } from 'src/utils/compare';
import { IconFont } from 'src/components/IconFont';
import './index.less';

const defaultColumn = {
  type: 'head',
  left_var_type: '',
  left_var_code: '',
  left_var_name: '',
  id: randomKey(),
};
const defaultCell = {
  type: 'body',
  conditions: '',
  id: randomKey(),
};
const defaultAction = {
  type: 'action',
  action: [],
  id: randomKey(),
};

const DecideTable = (props) => {
  const { variable, value, disabled = false, actions, logs, using_variables } = props;
  const [columns, setColumns] = useState([defaultColumn]);
  const [data, setData] = useState([[cloneDeep(defaultCell), cloneDeep(defaultAction)]]);
  const [logsList, setLogsList] = useState([]);

  useEffect(() => {
    if (value) {
      transferToUsefulData(value.rows);
    }
  }, [value]);

  useEffect(() => {
    if (logs && logs.rules && logs.rules.length > 0) {
      const conditionLogList = flattenDepth(logs.rules.map((item) => item.conditions));
      setLogsList(conditionLogList)
    }
  }, [props.logs])

  const isHit = (td) => {
    if (!logs || Object.keys(logs).length === 0 || !logs.rules || logs.rules.length === 0 || !td.conditions) return null
    const conditionLogList = logsList;
    const arr = td.conditions.map(item => {
      const con = conditionLogList.find(item2 => item2.id === item.id)
      return con && con.hit
    })
    let isHit = false
    if (arr.length === 0) {
      isHit = undefined
    } else if (arr.length === 1) {
      isHit = arr[0]
    } else {
      const junction_type = td.conditions[1].junction_type
      if (junction_type === 'and') {
        isHit = arr.reduce((acc, cur) => acc && cur)
      } else {
        isHit = arr.reduce((acc, cur) => acc || cur)
      }
    }
    return isHit
  }

  useImperativeHandle(props.createRef, () => ({
    // 暴露方法给父组件,收集验证值
    getValue: (cb, showError = true) => {
      const { error, value } = getValue(showError); // 验证数据
      cb(value, error);
    },
  }));

  // 右键事件
  const onColumnMenuClick = (key, rowIndex, colIndex) => {
    const tempColumn = [...columns];
    if (key === 'columnAdd') {
      const newDefaultColumn = { ...cloneDeep(defaultColumn), id: randomKey() };
      tempColumn.splice(colIndex + 1, 0, newDefaultColumn);
      setColumns(tempColumn);
      const newData = data.map((row) => {
        const tempRow = [...row];
        const newDefaultCell = { ...cloneDeep(defaultCell), id: randomKey() };
        tempRow.splice(colIndex + 1, 0, newDefaultCell);
        return tempRow;
      });
      setData(newData);
    } else if (key === 'columnDelete') {
      if (columns.length === 1) return null;
      tempColumn.splice(colIndex, 1);
      setColumns(tempColumn);
      setData(
        data.map((row) => {
          const tempRow = [...row];
          tempRow.splice(colIndex, 1);
          return tempRow;
        })
      );
    } else if (key === 'rowAdd') {
      const tempData = [...data];
      const newRow = columns.map(() => ({ ...cloneDeep(defaultCell), id: randomKey() }));
      newRow.push({ ...cloneDeep(defaultAction), id: randomKey() });
      tempData.splice(rowIndex + 1, 0, newRow);
      setData(tempData);
    } else if (key === 'rowDelete') {
      if (data.length === 1) return null;
      const tempData = [...data];
      tempData.splice(rowIndex, 1);
      setData(tempData);
    }
  };

  const contextMenu = (rowIndex, colIndex) => (
    <Menu onClick={({ key }) => onColumnMenuClick(key, rowIndex, colIndex)}>
      <Menu.Item key='rowAdd'>添加行</Menu.Item>
      <Menu.Item key='columnAdd'>添加列</Menu.Item>
      <Menu.Item key='rowDelete'>删除行</Menu.Item>
      <Menu.Item key='columnDelete'>删除列</Menu.Item>
    </Menu>
  );

  // 设置左变量
  const handleColLeftConditionChange = (value, index) => {
    const { var_code, var_type, var_name } = value;
    const tempcolumns = [...columns];
    tempcolumns[index] = {
      ...tempcolumns[index],
      left_var_code: var_code,
      left_var_type: var_type,
      left_var_name: var_name,
    };
    setColumns(tempcolumns);
  };

  // 设置条件
  const handleConditionChange = (value, rowIndex, columnIndex) => {
    const tempData = [...data];
    tempData[rowIndex][columnIndex].conditions = value;
    setData(tempData);
  };

  // 设置动作
  const handleActionChange = (value, rowIndex) => {
    const tempData = [...data];
    tempData[rowIndex][tempData[rowIndex].length - 1].action = value;
    setData(tempData);
  };

  // 根据后端返回的数据结构  构造table需要的数据结构
  const transferToUsefulData = (data) => {
    if (!data.length) return;
    const [newColumns, ...newData] = data.map((item) => item.cells);
    newColumns && setColumns(newColumns);
    newData && setData(newData);
  };

  // 获取最终的data
  const getValue = (showError) => {
    try {
      validate();
      const tempData = data.map((item) => ({
        cells: item,
      }));
      const rows = { rows: [{ cells: columns }, ...tempData] };
      return {
        error: null,
        value: rows,
      };
    } catch (error) {
      if (showError) {
        message.warning(error);
      }
      return {
        error: error,
        value: {},
      };
    }
  };

  const validate = () => {
    // 验证左变量
    columns.forEach((col) => {
      if (col && col.left_var_code === '') {
        throw '请设置左变量';
      }
    });
    // 验证条件 动作
    data.forEach((row) => {
      row.forEach((col) => {
        if (col.type === 'body') {
          if (col.conditions) {
            validateConditions(col.conditions);
          } else {
            throw '请设置条件';
          }
        }
        if (col.type === 'action') {
          if (col.action) {
            validateActions(col.action);
          } else {
            throw '请设置动作';
          }
        }
      });
    });
  };

  const compareData = flattenDepth(
    (props.compareData && props.compareData.rows && props.compareData.rows.map((row) => row.cells)) || []
  );
  return (
    <div className='table-wrap-con'>
      {/* <Button onClick={() => reset()}>重置</Button>
      <Button onClick={() => getValue()}>获取值</Button> */}
      <div className='tableContainer'>
        <div className='tableWrapper'>
          <div className='tableContent'>
            <table className={`decideTable ${disabled && 'disabled'}`}>
              <thead>
                <tr>
                  <td colSpan={columns.length + 1} className='headerCondition tableCell stickyLeft'>
                    条件
                  </td>
                  <td className='headerAction tableCell stickyRight'>动作</td>
                </tr>
                <tr>
                  <th className='tableCell tableCell-number stickyLeft'>序号</th>
                  {columns.map((column, index) => {
                    const { id } = column;
                    const { cell_id, ...detail } = column;

                    const cell =
                      compareData.find((cell) => {
                        return cell.id === id;
                      }) || {};
                    delete cell.cell_id;
                    const compareC = compareClass(
                      {
                        ...props,
                        value: { value: JSON.stringify(detail) },
                        compareData: JSON.stringify(cell) !== '{}'
                          ? {
                              value: JSON.stringify(cell),
                            }
                          : '',
                      },
                      'value'
                    );

                    return (
                      <th key={index}>
                        <Dropdown overlay={contextMenu(-1, index)} trigger={['contextMenu']}>
                          <div className={`tableCell ${compareC}`}>
                            <Row type='flex' align='middle' justify='space-between'>
                              <Col>
                                <PopValue
                                  value={{
                                    var_code: column.left_var_code,
                                    var_name: column.left_var_name,
                                    var_type: column.left_var_type
                                  }}
                                  type={column.left_var_type}
                                  event_id={column.left_event_id}
                                  placeholder={props.isCompare ? '' : '左变量'}
                                  variable={variable}
                                  using_variables={using_variables}
                                  onChange={(value) => handleColLeftConditionChange(value, index)}
                                  disabled={disabled}
                                  except={['literal']}
                                  isTxt={true}
                                  color={!disabled ? 'rgb(1, 116, 223)' : '#444444'}
                                  isLeft={true}
                                />
                              </Col>
                              <Col>
                                {!disabled && (
                                  <Dropdown overlay={contextMenu(-1, index)} trigger={['click']} disabled={disabled}>
                                    <IconFont
                                      type='iconsetting-1'
                                      className='setting-icon'
                                      style={{ fontSize: '16px' }}
                                    />
                                  </Dropdown>
                                )}
                              </Col>
                            </Row>
                          </div>
                        </Dropdown>
                      </th>
                    );
                  })}
                  <th className='tableCell stickyRight'>动作表达式</th>
                </tr>
              </thead>
              <tbody>
                {data.map((row, rowIndex) => {
                  return (
                    <tr key={rowIndex}>
                      <td className='tableCell tableCell-number stickyLeft'>{rowIndex + 1}</td>
                      {columns.concat({}).map((column, columnIndex) => {
                        const { id } = row[columnIndex];

                        const { cell_id, ...detail } = row[columnIndex];

                        const cell =
                          compareData.find((cell) => {
                            return cell.id === id;
                          }) || {};
                        delete cell.cell_id;
                        const compareC = compareClass(
                          {
                            ...props,
                            value: { value: JSON.stringify(detail) },
                            compareData: JSON.stringify(cell) !== '{}'
                              ? {
                                  value: JSON.stringify(cell),
                                }
                              : '',
                          },
                          'value'
                        );

                        return (
                          <td
                            key={`${rowIndex}-${columnIndex}`}
                            className={`${row[columnIndex].type === 'action' ? 'stickyRight' : ''}`}
                          >
                            {row[columnIndex].type === 'body' && (
                              <Dropdown overlay={contextMenu(rowIndex, columnIndex)} trigger={['contextMenu']}>
                                <div className={`tableCell ${compareC}`}>
                                  <Row type='flex' align='middle' justify='space-between'>
                                    <Col>
                                      <ConditionsIndex
                                        {...props}
                                        variable={variable}
                                        value={row[columnIndex].conditions}
                                        leftDisable={true}
                                        disabled={disabled}
                                        type='decide'
                                        leftConditionValue={{
                                          var_code: column.left_var_code,
                                          var_name: column.left_var_name,
                                          var_type: column.left_var_type,
                                        }}
                                        onChange={(value) => handleConditionChange(value, rowIndex, columnIndex)}
                                        isHit={isHit(row[columnIndex])}
                                        isCompare={false}
                                      />
                                    </Col>
                                    <Col>
                                      {!props.disabled && (
                                        <Dropdown
                                          overlay={contextMenu(rowIndex, columnIndex)}
                                          trigger={['click']}
                                          disabled={props.disabled}
                                        >
                                          <IconFont
                                            type='iconsetting-1'
                                            className='setting-icon'
                                            style={{ fontSize: '16px' }}
                                          />
                                        </Dropdown>
                                      )}
                                    </Col>
                                  </Row>
                                </div>
                              </Dropdown>
                            )}
                            {row[columnIndex].type === 'action' && (
                              <div className={`tableCell ${compareC}`}>
                                <Actions
                                  logs={logs}
                                  hitType={1}
                                  variable={variable}
                                  using_variables={using_variables}
                                  actions={actions}
                                  disabled={disabled}
                                  cellId={row[columnIndex].id}
                                  value={row[columnIndex].action}
                                  onChange={(value) => handleActionChange(value, rowIndex)}
                                  isCompare={false}
                                  riskTypes={props.riskTypes}
                                  isImportant={props.isImportant}
                                />
                              </div>
                            )}
                          </td>
                        );
                      })}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>
  );
};

export default DecideTable;
